package Records.Attributes;

import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FilenameUtils;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagException;
import org.jaudiotagger.tag.id3.AbstractID3v2Tag;
import org.jaudiotagger.tag.id3.ID3v24Frames;

public class LibraryMetadataExtract {

    private static String Location = "Directory";
    File songFile;

    public LibraryMetadataExtract(File f) {
        songFile = f;
    }

    public ArrayList extract() {
        System.out.println("LibraryMetadataExtract.extract()");
        ArrayList set = new ArrayList();
        if (FilenameUtils.isExtension(songFile.getAbsolutePath(), "mp3")) {
            MP3File mp3 = setMP3File(songFile);
            AbstractID3v2Tag ID3v2Tag = setv2Tag(mp3);

            String title = getTitle(ID3v2Tag, null);
            String artist = getArtist(ID3v2Tag, null);
            ArrayList<String> valSet = getSongAttributes.parseXml(artist, title, true);
            String album = getAlbum(ID3v2Tag, null, valSet);
            
            set.add(title + "_" + artist + "_" + album);
            set.add(title); //title
            set.add(artist); //artist
            set.add(album);//album
            set.add(getGenre(ID3v2Tag, null, valSet)); //genre
            set.add(AttributeCleaner.clean(valSet.get(5))); //energy
            set.add(AttributeCleaner.clean(valSet.get(4))); //danceability
            set.add(AttributeCleaner.clean(valSet.get(6))); //acousticness
            set.add(getBPM(ID3v2Tag, null, valSet)); //bpm
            set.add(getKey(ID3v2Tag, null, valSet)); //key
            //set.add(getMP3Image(songFile.getPath(), album, artist, title)); //image
            set.add(getAlbumArt.NewDir(title, artist, album)); //image
            set.add(songFile.getAbsolutePath().replaceAll("'", "~")); //filepathway
        } else if (FilenameUtils.isExtension(songFile.getAbsolutePath(), "m4a")) {
            Tag tag = setTag(songFile);

            //set.add(SongIDCounter.ID()); //song ID
            String title = getTitle(null, tag).replaceAll(",", "");
            String artist = getArtist(null, tag);
            ArrayList<String> valSet = getSongAttributes.parseXml(artist, title, false);
            String album = getAlbum(null, tag, valSet);

            set.add(title + "_" + artist + "_" + album);
            set.add(title); //title
            set.add(artist); //artist
            set.add(album);//album
            set.add(getGenre(null, tag, valSet)); //genre
            set.add(AttributeCleaner.clean(valSet.get(5))); //energy
            set.add(AttributeCleaner.clean(valSet.get(4))); //danceability
            set.add(AttributeCleaner.clean(valSet.get(6))); //acousticness
            set.add(getBPM(null, tag, valSet)); //bpm
            set.add(getKey(null, tag, valSet)); //key
            set.add(getAlbumArt.NewDir(title, artist, album)); //image
            set.add(songFile.getAbsolutePath().replaceAll("'", "~")); //filepathway
        }
        return set;
    }

    public static MP3File setMP3File(File song) {
        System.out.println("LibraryMetadataExtract.setMP3File(" + song.getAbsolutePath() + ")");
        MP3File g = null;
        try {
            g = (MP3File) AudioFileIO.read(song);

        } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException ex) {
            Logger.getLogger(LibraryMetadataExtract.class
                    .getName()).log(Level.SEVERE, null, ex);
        }
        return g;
    }

    public static AbstractID3v2Tag setv2Tag(MP3File mp3) {
        System.out.println("LibraryMetadataExtract.setv2Tag()");
        AbstractID3v2Tag v2tag = null;
        if (mp3 != null) {
            v2tag = mp3.getID3v2Tag();
        }
        return v2tag;
    }

    public static Tag setTag(File song) {
        System.out.println("LibraryMetadataExtract.setTag(" + song.getAbsolutePath() + ")");

        Tag tag = null;
        try {
            tag = AudioFileIO.read(song).getTag();

        } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException ex) {
            Logger.getLogger(LibraryMetadataExtract.class
                    .getName()).log(Level.SEVERE, null, ex);
        }
        return tag;
    }

    public static String getTitle(AbstractID3v2Tag v2tag, Tag tag) {
        System.out.println("LibraryMetadataExtract.getTitle()");
        String title;
        if (tag == null) {
            //get Title from v2Tag
            title = v2tag.getFirst(ID3v24Frames.FRAME_ID_TITLE);
        } else {
            //get Title from tag
            title = tag.getFirst(FieldKey.TITLE);
        }
        return title.replace("'", "").replace(",", "");
    }

    public static String getArtist(AbstractID3v2Tag v2tag, Tag tag) {
        System.out.println("LibraryMetadataExtract.getArtist()");
        String artist;
        if (tag == null) {
            //get artist from v2Tag
            artist = v2tag.getFirst(ID3v24Frames.FRAME_ID_ARTIST);
        } else {
            //get artist from tag
            artist = tag.getFirst(FieldKey.ARTIST);
        }
        return artist.replace("'", "").replace(",", "");
    }

    public static String getAlbum(AbstractID3v2Tag v2tag, Tag tag, ArrayList<String> valSet) {
        System.out.println("LibraryMetadataExtract.getAlbum()");
        String album;
        if (tag == null) {
            //get artist from v2Tag
            album = v2tag.getFirst(ID3v24Frames.FRAME_ID_ALBUM);
        } else {
            //get artist from tag
            album = tag.getFirst(FieldKey.ALBUM);
        }
        if (album.equals("")) {
            album = AttributeCleaner.clean(valSet.get(7));
        }
        return album.replace("'", "").replace(",", "");
    }

    public static String getGenre(AbstractID3v2Tag v2tag, Tag tag, ArrayList<String> valSet) {
        System.out.println("LibraryMetadataExtract.getGenre()");
        String genre;
        if (tag == null) {
            //get genre from v2Tag
            genre = v2tag.getFirst(ID3v24Frames.FRAME_ID_GENRE);
        } else {
            //get genre from tag
            genre = tag.getFirst(FieldKey.GENRE);
        }
        if (genre.equals("")) {
            genre = AttributeCleaner.clean(valSet.get(8));
        }
        return genre;
    }

    public static String getBPM(AbstractID3v2Tag v2tag, Tag tag, ArrayList<String> valSet) {
        System.out.println("LibraryMetadataExtract.getBPM()");
        String BPM;
        if (tag == null) {
            BPM = getSongAttributes.BPM(v2tag.getFirst(ID3v24Frames.FRAME_ID_BPM));
        } else {
            BPM = getSongAttributes.BPM(tag.getFirst(FieldKey.BPM));
        }
        if (BPM.equals("")) {
            BPM = AttributeCleaner.clean(valSet.get(2));
        }
        return BPM;
    }

    public static String getKey(AbstractID3v2Tag v2tag, Tag tag, ArrayList<String> valSet) {
        System.out.println("LibraryMetadataExtract.getKey()");
        String key;
        if (tag == null) {
            key = v2tag.getFirst(ID3v24Frames.FRAME_ID_INITIAL_KEY).replace("m", "");
        } else {
            key = tag.getFirst(FieldKey.KEY).replace("m", "");
        }
        if (key.equals("")) {
            key = AttributeCleaner.clean(valSet.get(3));
        }
        return key;
    }

    public static String getMP3Image(String path, String album, String artist, String title) {
        System.out.println("LibraryMetadataExtract.getMP3Image()");
        String image = "";
        Mp3File song;
        try {
            song = new Mp3File(path);
            ID3v2 id3v2tag = song.getId3v2Tag();
            byte[] imData = id3v2tag.getAlbumImage();
            getAlbumArt.SaveImageFromLibrary(imData, album, artist, title);
        } catch (IOException | UnsupportedTagException | InvalidDataException ex) {
            image = getAlbumArt.NewDir(title, artist, album);
        }
        return image;
    }
}
